package com.gec.realms;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;


import com.gec.dao.RoleMapper;
import com.gec.dao.UserMapper;
import com.gec.domain.User;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;


import org.springframework.beans.factory.annotation.Autowired;

public class MyAuthorizationRealm extends AuthorizingRealm {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    /**---------------------[初始化用户数据]----------------------*/
    Map<String, User> users = new HashMap();
    public MyAuthorizationRealm(){

    }

    void setPermission(String[] data, Set set){
        for(String p : data){
            set.add( p );
        }
    }

    /*---------------------[初始化权限相关数据]-------------------*/
    //{ps}哪些角色有哪些权限
    Map<String,Set<String>> rolePerMap = new HashMap<>();
    public void initRealm(){
        //暂时写死，后面写活
        Set<String> r0 =roleMapper.getRolePermission("r0*");//管理员
        Set<String> r01 =roleMapper.getRolePermission("r01");//Boss
        Set<String> r02 =roleMapper.getRolePermission("r02");//leader
        Set<String> r03 =roleMapper.getRolePermission("r03");//manager
        Set<String> r05 =roleMapper.getRolePermission("r05");//Employee
        rolePerMap.put("r0*", r0);
        rolePerMap.put("r01", r01);
        rolePerMap.put("r02", r02);
        rolePerMap.put("r03", r03);
        rolePerMap.put("r05", r05);
    }

    /*---------------------- [END] ----------------------*/
    //Cation: 是做登录认证的。
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token )
            throws AuthenticationException {
        //{1}得到用户名。
        String principal = (String)token.getPrincipal();
        //{2}得到用户的密码。
        char[] credentials = (char[])token.getCredentials();
        String password = new String(credentials);

        //------------------------------------------------------------

        //{3}从数据库中获取用户信息(数据库中的用户)
        User dbUser = userMapper.getUserByName(principal);
        if( dbUser==null ){
            return null;  //认证器收到 null 值, 抛出未知用户异常。
        }
        //{4}加密这个信息类稍后再用。
//		new SimpleAuthenticationInfo(
//				principal, hashedCredentials,
//				credentialsSalt, realmName );

        //------------------------------------------------------------

        //{5}创建认证信息类对象 (不加密的)。[认证器自动判断密码]
        SimpleAuthenticationInfo info =
                new SimpleAuthenticationInfo(
                        dbUser, dbUser.getPassword(), getName());
        //{1}数据库用户    {2}数据库的密码      {3}realm名称
        return info;
    }


    //Zation: 是做用户授权 与 权限认证的。
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection collection) {
        //{1}获取主身份信息。(做认证时放入的是 user, 所以这里拿到的是 user)
        User priPrincipal = (User)collection.getPrimaryPrincipal();

        //------------------------------------------------------------
        //{2}获取角色ID
        String roleId = priPrincipal.getPrimaryRole().getId();
        //{3}通过角色Id获取角色权限。【很早就取到数据了，现在从缓存中获取】
        Set<String> permissions = rolePerMap.get(roleId);//[已测试andy无权限]
        //------------------------------------------------------------
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //{4}添加一个角色
//		info.addRole( roleName );
        //{5}还可以设置权限信息。
        info.setStringPermissions( permissions );
        //{6}最后将信息对象返回给授权认证器处理。
        return info;
    }

}
